#pragma once
#include <iostream>
#include <pthread.h>
#include <string>
#include <functional>
#include <cassert>
namespace ThreadNs
{
    typedef std::function<void *(void *)> func_t; // 定义一个函数对象类型，它的返回值和参数都是void*
    const int NUM = 1024;

    class Thread
    {
    private:
        // 因为形参有个this指针，所以弄成static
        static void *start_routine(void *args) // 这里的args就是 start()的ctx
        {
            Thread *_this = static_cast<Thread *>(args);
            return _this->callback();
        }
        void *callback()
        {
            return _func(_args);
        }

    public:
        // 构造函数
        Thread()
        {
            char nameBuffer[NUM];
            snprintf(nameBuffer, sizeof(nameBuffer), "thread-%d", threadNum++);
            _name = nameBuffer;
        }
        void start(func_t func, void *args = nullptr) // 线程启动
        {
            _func = func;
            _args = args;
            int n = pthread_create(&_tid, nullptr, start_routine, this);
            assert(n == 0);
            (void)n;
        }
        void join()
        {
            int n = pthread_join(_tid, nullptr);
            assert(n == 0);
            (void)n;
        }
        std::string threadName()
        {
            return _name;
        }
        ~Thread()
        {
        }

    private:
        std::string _name;    // 线程的名字
        func_t _func;         // 线程的回调函数
        void *_args;          // 喂给线程的参数
        pthread_t _tid;       // 线程ID
        static int threadNum; // 线程编号，最好自己再加个锁
    };
    int Thread::threadNum = 1;
    // 异常和if。意料之外
    // assert。意料之中。99%概率为真。
}